from neo4j import GraphDatabase
from config import HOST,PORT,USER,PWD
class KGServer():
    def __init__(self):
        self.driver = GraphDatabase.driver("bolt://{host}:{port}".format(host=HOST,port=PORT), auth=(USER, PWD))  # 认证连接数据

    def select(self, cypter_str):
        with self.driver.session() as session:
            results = session.run(cypter_str)
            return results

    def create_node(self,cypter_str):
        with self.driver.session() as session:
            results = session.run(cypter_str)
            for i in results:
                if i:
                    return self.record2properties(i)
                else:
                    return 0
    def create_rel(self,cypter_str):
        with self.driver.session() as session:
            results = session.run(cypter_str)
            for i in results:
                if i:
                    return self.r_obj_handel(i)
                else:
                    return 0


    @staticmethod
    def dic2args(dic):
        args = '{'
        for i in dic:
            args += i + ':'
            dic[i] = '\'%s\'' % dic[i]
            args += '%s,' % dic[i]
        else:
            args = args.rstrip(',')
            args += '}'
        return args

    @staticmethod
    def dic2str(dic):
        s = ''
        if len(dic) > 1:
            for k, v in dic.items():
                s += 'n.{k}=~\'.*{v}.*\' and '.format(k=k, v=v)
            s = s.rstrip('and ')
        else:
            for k, v in dic.items():
                s += 'n.{k}=~\'.*{v}.*\''.format(k=k, v=v)
        return s

    @staticmethod
    def record2properties(record_obj):
        node_data = {'id': record_obj[0].id, 'label': list(record_obj[0].labels)[0]}
        propertie = dict(record_obj[0].items())
        node_data.update(propertie)
        return node_data

    @classmethod
    def node2properties(cls,node_obj):
        node_data = {'id':node_obj.id}
        node_data['uuid'] = dict(node_obj.items()).get('uuid')
        node_data['name'] = dict(node_obj.items()).get('name')
        return node_data

    @staticmethod
    def rel2properties(rel_obj):
        rel = rel_obj[0].relationships[0]
        st_node_data = KGServer.node2properties(rel.start_node)
        en_node_data = KGServer.node2properties(rel.end_node)
        rel_data = {
            'id': rel.id,
            'type': rel.type,
            'properties': dict(rel.items()),
            'start_node_id': st_node_data['id'],
            'start_node_uuid': st_node_data['uuid'],
            'start_node_name': st_node_data['name'],
            'end_node_id': en_node_data['id'],
            'end_node_uuid': en_node_data['uuid'],
            'end_node_name': en_node_data['name']
        }
        return rel_data

    @staticmethod
    def r_obj_handel(rel_obj):
        data = {
            'id': rel_obj[0].id,
            'type': rel_obj[0].type,
            'properties': dict(rel_obj[0].items()),
            'start_node_id': rel_obj[0].start,
            'end_node_id': rel_obj[0].end,
        }
        return data

    def node_is_exist(self,uuid):
        res = self.select(
            "MATCH (n {uuid:'%s'}) RETURN n"%uuid
        )
        for i in res:
            if i:
                return 1
            else:
                return 0

    def rel_is_exist(self,st_uuid,en_uuid,rel_type):
        cypter_str = "MATCH p=(s {uuid:'%s'})-[r:%s]->(e {uuid:'%s'}) RETURN p"%(st_uuid,rel_type,en_uuid)
        res = self.select(cypter_str)
        for i in res:
            if i:
                return self.rel2properties(i)
            else:
                return 0
    def node_handel(self,node_obj):
        data = {
            'id':node_obj.id,
            'label':list(node_obj.labels)[0],

        }
        data.update(dict(node_obj.items()))
        return data
    def rel_handel(self,rel_obj):
        st_node_data = KGServer.node2properties(rel_obj.start_node)
        en_node_data = KGServer.node2properties(rel_obj.end_node)
        rel_data = {
            'id': rel_obj.id,
            'type': rel_obj.type,
            'properties': dict(rel_obj.items()),
            'start_node_id': st_node_data['id'],
            'start_node_uuid': st_node_data['uuid'],
            'end_node_id': en_node_data['id'],
            'end_node_uuid': en_node_data['uuid']
        }
        return rel_data


if __name__ == '__main__':
    import os
    import uuid
    import requests
    import time

    kg_server = KGServer()
    node_type = 'Ship'
    filepath = os.path.join(os.path.dirname(__file__),"%s.txt"%node_type)
    # print(filepath)
    def load_data():
        res = kg_server.select("MATCH (n:%s) RETURN n"%node_type)
        f = open(filepath,'w')
        for record in res:
            node_data = kg_server.record2properties(record)
            node_name_uuid = str(uuid.uuid5(uuid.NAMESPACE_DNS, "{node_id}{node_name}".format(node_id=node_data['%sID'%node_type],node_name=node_data['name'])))
            f.write("%s,%s\n"%(node_data['%sID'%node_type],node_name_uuid))
        f.close()


    def save_data():
        with open(filepath,'r') as f:
            for line in f:
                ID,node_name_uuid = line.strip().split(',')
                data = {'ID':ID,'node_name_uuid':node_name_uuid,'node_type':node_type}
                res = requests.post("http://localhost:5000/update" , data=data).json()
                time.sleep(0.05)
                if res != 'ok':
                    break



    # load_data()
    # save_data()

    # flask 启动
    #uwsgi3.6 - d - -ini / opt / KG / kg_server / uwsgi.ini

    # django自动启动
    #uwsgi3.6 - d - -ini / opt / KG / kg_manager / uwsgi.ini

